package org.yn.auth.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.yn.auth.dto.LoginDTO;
import org.yn.auth.service.ILoginService;
import org.yn.base.constants.WxConstants;
import org.yn.base.util.HttpUtil;
import org.yn.base.util.MD5Utils;
import org.yn.emp.mapper.EmployeeMapper;
import org.yn.exception.AssertUtil;
import org.yn.exception.ResponseCode;
import org.yn.user.domain.Logininfo;
import org.yn.user.domain.Wxuser;
import org.yn.user.mapper.LogininfoMapper;
import org.yn.user.mapper.WxuserMapper;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements ILoginService {
    @Autowired
    EmployeeMapper employeeMapper;

    @Value("${MD5.preFix}")
    String preFix;

    @Value("${MD5.endFix}")
    String endFix;

//    @Override
//    public Map<String, Object> login(LoginDTO user) {
//        // 先判断user的账号和密码是否为空
//        if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){
//            throw  new RuntimeException("请输入账号和密码");
//        }
//
//        //查询账号 的密码 来判断
//        //没有查到账号
//        Employee employee = employeeMapper.selectByName(user.getUsername());
//    if (Objects.isNull(employee)){
//        throw new RuntimeException("用户不存在");
//    }
//
//    // 判断密码
//        if (!employee.getPassword().equals(user.getPassword())){
//            throw new RuntimeException("密码错误");
//        }
//
//        //将user存入map
//        //生成uuid 给全局loginmap 和 employee结合
//
//        String uuid1 = UUID.randomUUID().toString();
//        //方便测试现在将uuid写成固定的
//        String uuid ="test";
//
//        System.out.println("生成的uuid:"+uuid);
//        LoginContext.loginMap.put(uuid,employee);
//
//        //new一个hasmap 返回给前端
//        //将employee的pwd和id设置为null（敏感信息
//        employee.setPassword(null);
////        employee.setId(null);
//
////        返回的是”token“+UUID
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("token",uuid);
//        map.put("user",employee);
//        return map;
//    }
@Autowired
private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private WxuserMapper wxuserMapper;

    @Override
    public Map<String, Object> login(LoginDTO user) {
        // 参数校验
            // 校验type不能为空
        AssertUtil.isNotNull(user.getType(), ResponseCode.RESPONSE_CODE_500);

        // 查询账号是否存在,
            // 不存在说明账号错误,返回错误信息
        Logininfo logininfo = logininfoMapper.selectByAccount(user.getAccount(),user.getType());
        AssertUtil.isNotNull(logininfo,ResponseCode.RESPONSE_CODE_40023);

        // 比对密码,密码不正确说明密码错误,返回错误信息
        String salt = logininfo.getSalt();
        String password = MD5Utils.encrypByMd5(preFix+salt+user.getPassword()+endFix);

        AssertUtil.isEq(password,logininfo.getPassword(),ResponseCode.RESPONSE_CODE_40023);

        return LoginSuccess(logininfo);
    }

    @Override
    public Map<String, Object> wxLogin(String code) {
        //根据code拿到 微信用户的accessToken 和 openid
        String accessUrl = WxConstants.GET_ACK_URL.replace("APPID", WxConstants.APPID)
                .replace("SECRET", WxConstants.SECRET)
                .replace("CODE", code);

        //发起请求
        String accessStr = HttpUtil.httpGet(accessUrl);

        //拿到的数据为字符串 需要转换为对象
        JSONObject accessObj = JSONObject.parseObject(accessStr);
        System.out.printf("--accessObj---"+accessObj);

        //把对象里面的accessToken openid取出来
        String access_token = accessObj.getString("access_token");
        String openid = accessObj.getString("openid");


        //根据查到的openid去数据库查找 有没有对应wxuser
       Wxuser wxuser= wxuserMapper.selectByOpenid(openid);

       // 判断是否有用户 如果找到 说明之前注册过，直接免密登录
                        //如果没有  说明新用户 ,需要返回  access_token  openid 前端跳转到绑定页面

        if (Objects.nonNull(wxuser)){   //如果不为空   直接免密登录，token和用户信息存放到redis
            //根据openid求出logininfo信息，然后存放redis 并返回给前端
           Logininfo logininfo= logininfoMapper.selectByOpenid(openid);

            Map<String, Object> map = LoginSuccess(logininfo);  //这个里面包含了将 token信息和user信息放在redis中的功能

            return map; //token +User 返回给前端
        }else{   //不存在 跳转到绑定页面
            HashMap<String, Object> map = new HashMap<>();
            map.put("access_token",access_token);//    access_token
            map.put("openid",openid);    //openid
            map.put("message","noBind");     //message

            return map;

        }





    }

    /**
     * 将登录 成功 之后的返回token+用户信息封装成方法
     * @param logininfo
     * @return
     */
    public Map<String, Object> LoginSuccess(Logininfo logininfo) {
        // 将登录信息存入redis中,
        // key->uuid(token) value->logininfo,设置30分钟过期时间
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);

        // 将token和logininfo信息返回给前端
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        // 清除敏感信息
        logininfo.setSalt("");
        logininfo.setPassword("");
        map.put("loginUser", logininfo);
        return map;
    }


}
